﻿using System;


namespace Sencha.Serialization.Bson.Serializers
{
	public class BsonBinarySerializer : TypeSerializer<BsonBinary>
	{
		public override BsonBinary Deserialize(IJsonReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");

			if (reader is IBsonReader)
				return this.DeserializeBson(reader as IBsonReader);

			// { "$binary" : "<bindata>", "$type" : "<t>" }
			// http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON

			reader.ReadObjectBegin();
			var base64Binary = reader.ReadMember<string>("$binary");
			var subtypeHex = reader.ReadMember<string>("$type");
			reader.ReadObjectEnd(false);


			var subType = byte.Parse(subtypeHex, System.Globalization.NumberStyles.HexNumber);
			var binary = Convert.FromBase64String(base64Binary);

			var value = new BsonBinary(subType, binary);
			return value;
		}
		private BsonBinary DeserializeBson(IBsonReader reader)
		{
			if (reader.Token != BsonToken.Binary)
				throw new Exceptions.UnexpectedBsonToken(reader, BsonToken.Binary);

			var binary = (BsonBinary)reader.RawValue;
			return binary;
		}
		public override void Serialize(IJsonWriter writer, BsonBinary value)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");

			if (value == null)
			{
				writer.WriteNull();
				return;
			}

			if (writer is IBsonWriter)
			{
				this.SerializeBson(writer as IBsonWriter, value);
				return;
			}

			writer.WriteObjectBegin();
			writer.WriteMember<string>("$binary",value.ToBase64());
			writer.WriteMember<string>("$type", value.SubType.ToString("X2"));
			writer.WriteObjectEnd();
		}
		private void SerializeBson(IBsonWriter writer, BsonBinary value)
		{
			writer.Write(BsonToken.Binary, value);
		}
	}
}
